home *** CD-ROM | disk | FTP | other *** search
- /*
- File: IMAAudioQueue.c
-
- Contains: Definition of operations for IMAAudioQueue, a queue datatype
- for IMA audio sample data.
-
- Copyright: © 1997-1999 by Apple Computer, Inc., all rights reserved.
-
- */
-
-
-
- #include "IMAAudioQueue.h"
- #include "IMAAudioPayload.h"
- #include <Math64.h>
-
-
-
- static
- RTPMPSampleDataParams **
- __CopySampleDataParams(
- const RTPMPSampleDataParams * inSampleDataParams )
- {
- RTPMPSampleDataParams ** theResult;
-
-
- theResult =
- REINTERPRET_CAST( RTPMPSampleDataParams ** )(
- NewHandle( sizeof( *inSampleDataParams ) ) );
-
- **theResult = *inSampleDataParams;
-
- return( theResult );
- }
-
-
-
- static
- RTPMPSampleDataParams *
- __LockSampleDataParams(
- RTPMPSampleDataParams ** inSampleDataParams )
- {
- Handle theHandle = REINTERPRET_CAST( Handle )( inSampleDataParams );
-
-
- if( HandleZone( theHandle ) == SystemZone() )
- HLock( theHandle );
- else
- HLockHi( theHandle );
-
- return( *inSampleDataParams );
- }
-
-
-
- static
- void
- __DisposeSampleDataParams(
- RTPMPSampleDataParams ** inSampleDataParams )
- {
- DisposeHandle( REINTERPRET_CAST( Handle )( inSampleDataParams ) );
- }
-
-
-
- static
- UInt64
- __ConsumedDuration(
- IMAAudioQueue * inQueue,
- UInt32 inChannel )
- {
- UInt32 theFrameCount;
- UInt64 theSampleCount;
- UInt64 theResult;
-
-
- theFrameCount =
- ( inQueue->__itsConsumedFrameCount + inQueue->__itsChannelCount - inChannel - 1 ) /
- inQueue->__itsChannelCount;
-
- theSampleCount =
- U64Multiply(
- U64SetU( theFrameCount ), U64SetU( kIMAAudioPayloadFrameSampleCount ) );
-
- theResult =
- S64Div(
- U64Multiply(
- theSampleCount,
- U64SetU( STATIC_CAST( UInt32 )( kIMAAudioPayloadRTPTimeScale ) << 16 ) ),
- S64SetU( inQueue->__itsIncomingSampleRate ) );
-
- return( theResult );
- }
-
-
-
- static
- UInt64
- __DequeuedDuration(
- IMAAudioQueue * inQueue,
- UInt32 inChannel )
- {
- UInt32 theFrameCount;
- UInt64 theSampleCount;
- UInt64 theResult;
-
-
- theFrameCount =
- ( inQueue->__itsDequeuedFrameCount + inQueue->__itsChannelCount - inChannel - 1 ) /
- inQueue->__itsChannelCount;
-
- theSampleCount =
- U64Multiply(
- U64SetU( inQueue->__itsDequeuedFrameCount / inQueue->__itsChannelCount ),
- U64SetU( kIMAAudioPayloadFrameSampleCount ) );
-
- theResult =
- S64Div(
- U64Multiply(
- theSampleCount,
- U64SetU( STATIC_CAST( UInt32 )( kIMAAudioPayloadRTPTimeScale ) << 16 ) ),
- S64SetU( inQueue->__itsOutgoingSampleRate ) );
-
- return( theResult );
- }
-
-
-
- static
- void
- __GetNextFrame(
- IMAAudioQueue * inQueue,
- IMAAudioQueueElement * outElement )
- {
- RTPMPSampleDataParams ** theSampleDataParams;
-
-
- theSampleDataParams =
- STATIC_CAST( RTPMPSampleDataParams ** )( QueueHead( &inQueue->__itsQueue ) );
-
- if( inQueue->__itsCurrentOffset >= ( **theSampleDataParams ).dataLength )
- {
- inQueue->__itsCurrentOffset = 0;
-
- QueueDequeue( &inQueue->__itsQueue );
- __DisposeSampleDataParams( theSampleDataParams );
-
- theSampleDataParams =
- STATIC_CAST( RTPMPSampleDataParams ** )( QueueHead( &inQueue->__itsQueue ) );
- }
-
- if( inQueue->__itsCurrentOffset == 0 )
- __LockSampleDataParams( theSampleDataParams );
-
- outElement->itsChannel = inQueue->__itsConsumedFrameCount % inQueue->__itsChannelCount;
-
- outElement->itsTimestamp =
- S64Add(
- inQueue->__itsStartTime,
- __DequeuedDuration( inQueue, outElement->itsChannel ) );
-
- outElement->itsSampleDataParams = *theSampleDataParams;
- outElement->itsOffset = inQueue->__itsCurrentOffset;
-
- inQueue->__itsCurrentOffset += sizeof( IMAAudioFrame );
- --inQueue->__itsFrameCount;
- inQueue->__itsConsumedFrameCount++;
- }
-
-
-
- static
- void
- __Reset(
- IMAAudioQueue * inQueue )
- {
- QueueInitialize( &inQueue->__itsQueue );
- inQueue->__itsStartTime = S64SetU( 0 );
- inQueue->__itsFrameCount = 0;
- inQueue->__itsCurrentOffset = 0;
- inQueue->__itsConsumedFrameCount = 0;
- inQueue->__itsDequeuedFrameCount = 0;
- }
-
-
-
- extern
- void
- IMAAudioQueueInitialize(
- IMAAudioQueue * inQueue )
- {
- __Reset( inQueue );
-
- IMAAudioQueueSetFlowControl( inQueue, 0, 0, 1 );
- }
-
-
-
- extern
- UnsignedFixed
- IMAAudioQueueSetFlowControl(
- IMAAudioQueue * inQueue,
- UnsignedFixed inIncomingSampleRate,
- UnsignedFixed inOutgoingSampleRate,
- UInt16 inChannelCount )
- {
- UnsignedFixed theResult;
-
-
- if( inIncomingSampleRate >= inOutgoingSampleRate )
- theResult = inOutgoingSampleRate;
- else
- theResult = inIncomingSampleRate;
-
- if( inQueue->__itsFrameCount )
- {
- if(
- inIncomingSampleRate != inQueue->__itsIncomingSampleRate ||
- theResult != inQueue->__itsOutgoingSampleRate )
- {
- IMAAudioQueueFlush( inQueue );
- }
- }
-
- inQueue->__itsIncomingSampleRate = inIncomingSampleRate;
- inQueue->__itsOutgoingSampleRate = theResult;
- inQueue->__itsChannelCount = inChannelCount;
-
- return( theResult );
- }
-
-
-
- extern
- UInt32
- IMAAudioQueueCount(
- const IMAAudioQueue * inQueue )
- {
- UInt32 theResult;
- UInt64 theIncomingFrameCount;
- UInt64 theIncomingSampleRate;
- UInt64 theDequeuedFrameCount;
- UInt64 theOutgoingSampleRate;
- UInt64 thePendingTime;
-
-
- if( inQueue->__itsIncomingSampleRate && inQueue->__itsFrameCount )
- {
- theIncomingFrameCount =
- U64SetU( inQueue->__itsConsumedFrameCount + inQueue->__itsFrameCount );
-
- theIncomingSampleRate = U64SetU( inQueue->__itsIncomingSampleRate );
- theDequeuedFrameCount = U64SetU( inQueue->__itsDequeuedFrameCount );
- theOutgoingSampleRate = U64SetU( inQueue->__itsOutgoingSampleRate );
-
- thePendingTime =
- U64Subtract(
- U64Multiply( theOutgoingSampleRate, theIncomingFrameCount ),
- U64Multiply( theIncomingSampleRate, theDequeuedFrameCount ) );
-
- theResult = U32SetU( U64Div( thePendingTime, theIncomingSampleRate ) );
-
- if( U64Mod( thePendingTime, theIncomingSampleRate ) )
- theResult++;
- }
-
- else
- {
- theResult = 0;
- }
-
- return( theResult );
- }
-
-
-
- extern
- RTPMPSampleDataParams *
- IMAAudioQueueEnqueue(
- IMAAudioQueue * inQueue,
- const RTPMPSampleDataParams * inSampleDataParams )
- {
- RTPMPSampleDataParams * theResult;
-
-
- theResult =
- ( RTPMPSampleDataParams * ) QueueEnqueue(
- &inQueue->__itsQueue, __CopySampleDataParams( inSampleDataParams ) );
-
- if( theResult )
- {
- if( inQueue->__itsFrameCount == 0 && inQueue->__itsConsumedFrameCount == 0 )
- inQueue->__itsStartTime = inSampleDataParams->timeStamp;
-
- inQueue->__itsFrameCount +=
- inSampleDataParams->dataLength / sizeof( IMAAudioFrame );
- }
-
- return( theResult );
- }
-
-
-
- extern
- Boolean
- IMAAudioQueueDequeue(
- IMAAudioQueue * inQueue,
- IMAAudioQueueElement * outElement )
- {
- Boolean theResult = false;
- UInt32 theInitialFrameCount = inQueue->__itsFrameCount;
-
-
- while( inQueue->__itsFrameCount && !theResult )
- {
- __GetNextFrame( inQueue, outElement );
-
- theResult =
- U64Compare(
- __ConsumedDuration( inQueue, outElement->itsChannel ),
- __DequeuedDuration( inQueue, outElement->itsChannel ) ) > 0;
- }
-
- if( theInitialFrameCount > inQueue->__itsFrameCount && theResult )
- inQueue->__itsDequeuedFrameCount++;
- else
- theResult = false;
-
- return( theResult );
- }
-
-
-
- extern
- void
- IMAAudioQueueFlush(
- IMAAudioQueue * inQueue )
- {
- UInt32 theCount;
- RTPMPSampleDataParams ** theSampleDataParams;
-
-
- for( theCount = QueueCount( &inQueue->__itsQueue ); theCount; --theCount )
- {
- theSampleDataParams =
- STATIC_CAST( RTPMPSampleDataParams ** )( QueueDequeue( &inQueue->__itsQueue ) );
-
- __DisposeSampleDataParams( theSampleDataParams );
- }
-
- __Reset( inQueue );
- }
-